<?php

class tfmailsBgTask extends sfBaseTask {

    protected function configure() {
        // add your own arguments here
//     $this->addArguments(array(
//       new sfCommandArgument('no-send', sfCommandArgument::REQUIRED, 'Don\'t send emails', false),
//     ));



        $this->addOptions(array(
            new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application', 'frontend'),
            new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environment', 'prod'),
            // add your own options here
            new sfCommandOption('continuous', null, sfCommandOption::PARAMETER_NONE, 'Works on continuous Campaigns')
        ));

        $this->namespace = 'tfmails';
        $this->name = 'work';
        $this->briefDescription = '';
        $this->detailedDescription = <<<EOF
The [tfmails:work|INFO] task send mails for a campaign.
If called with the [--continuous|INFO] parameter sends mails for all open
continuous Campaigns.

Call it with:

  [php symfony tfmails:work|INFO]
EOF;
    }

    protected function execute($arguments = array(), $options = array()) {
        $file_logger = new sfFileLogger($this->dispatcher, array(
                    'file' => $this->configuration->getRootDir() . '/log/work.log'
                ));
        $this->dispatcher->connect('command.log', array($file_logger, 'listenToLogEvent'));


        $clickBaseUrl = sfConfig::get('app_click_base_url');

        $this->logSection('25Mails-work', 'Initializing...', 80, 'INFO'); // ERROR, INFO or COMMAND
        // initialize the database connection
        $databaseManager = new sfDatabaseManager($this->configuration);
//        $connection = $databaseManager->getDatabase($options['connection'])->getConnection();

        $mailer = $this->getMailer();
        $campaigns = array();
        if ($options['continuous']) {//loads every continuous campaign and processes them
            $campaigns = Doctrine::getTable('Campaign')->getContinuousCampaigns();
        } else { //loads only ONE Campaign and processes it
            $campaign = Doctrine::getTable('Campaign')->getNextOpenCampaign();
            if ($campaign) {
                $campaigns[] = $campaign;
            }
            //        $campaign = Doctrine::getTable('Campaign')->findOneByName('Newsletter n12');
        }
        $this->log('Loaded ' . count($campaigns) . ' Campaign(s).');
        foreach ($campaigns as $campaign) {
            $this->log('Loaded \'' . $campaign->getName() . '\' Campaign.');

            // put Campaign in ONGOING status
            $campaign->setStatus('ONGOING');
            $campaign->save();
            $this->log('    Campaign ' . $campaign->getCampaignId() . ' is now "ONGOING".');
            // load the template for this Campaign
            $template = $campaign->getTemplate();
            //retrieve number of recipients of this campaign applying the recipientsFilter query
            $recipientCount = Doctrine::getTable('Recipient')->countRecipientsForFilter($campaign->getRecipientsFilter(), $campaign->getTagsFilter());
            $this->log('    Campaign has ' . $recipientCount . ' recipients.');
            //because recipient number can be huge we paginate them
            $pageSize = sfConfig::get('app_mail_batch_size');
            $numpages = ceil($recipientCount / $pageSize);
            for ($i = 1; $i <= $numpages; $i++) {
                $skipped = false;
                $this->log('        Sending mails to block ' . $i);
                $recipients = Doctrine::getTable('Recipient')->getRecipientsForFilter($campaign->getRecipientsFilter(), $campaign->getTagsFilter(), $i, $pageSize);
                foreach ($recipients as $recipient) {
                    $mail = Doctrine::getTable('Mail')->findOneByRecipientIdAndCampaignId($recipient->getRecipientId(), $campaign->getCampaignId());
                    if (!$mail) {
                        //send the mail to the recipient
                        $message = new TfMailsMessage($template, $recipient, $clickBaseUrl, $campaign->getCampaignId());
                        $this->log('            Sending mail to ' . $recipient->getEmail());
                        $mail = new Mail();
                        $mail->setCampaign($campaign);
                        $mail->setRecipient($recipient);
                        $mail->setTemplate($template);
                        $mail->setSendingDate(date('Y-m-d H:i:s', time()));
                        $mail->setStatus('SENDING'); //status is SENDING
                        $mail->save();
                        if ($mailer->send($message) > 0) {
                            $mail->setStatus('SENT'); //status is SENT
                        } else {
                            $mail->setStatus('ERROR'); //status is ERROR
                            $mail->setNotes('Unable to send mail');
                        }
                        $mail->save();
                    } else {
                        $this->log('            Skipping recipient ' . $recipient->getEmail());
                        $skipped = true;
                    }
                    $recipient->free(true);
                    $mail->free();
                    unset ($recipient,$mail, $message );
                }
                $recipients->free(true);
                unset ($recipients);
                if (!$skipped) { //sleeps before sending next block
                    sleep(sfConfig::get('app_mail_batch_sleep'));
                }
            }

            // if Campaign is continuous put it back in TO_DO status, else put it in DONE
            if ($campaign->getContinuous()) {
                $this->log('    Putting back Campaign ' . $campaign->getCampaignId() . ' in TO_DO status');
                $campaign->setStatus('TO_DO');
                $campaign->save();
            } else {
                $this->log('    Putting Campaign ' . $campaign->getCampaignId() . ' in DONE status');
                $campaign->setStatus('DONE');
                $campaign->save();
            }
        }
    }

}
